# Create your views here.
import random

from django.contrib.auth import authenticate, login as django_login
from django.contrib.auth import REDIRECT_FIELD_NAME


from django.utils.translation import ugettext as _

from facebook import Facebook

from fbconnect.__init__ import *

if not settings.AUTH_PROFILE_MODULE:
    raise SiteProfileNotAvailable
try:
    app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
    Profile = models.get_model(app_label, model_name)
except (ImportError, ImproperlyConfigured):
    raise SiteProfileNotAvailable

if not Profile:
    raise SiteProfileNotAvailable

from fbconnect.forms import FBConnectForm, UsernameForm

ERR = _('Sorry, but we could not verify your credentials')

def login(request, uid = None):
    is_authed = request.user.is_authenticated()

    # check the request method
    if not request.is_ajax() and not request.method == "POST":
        return HttpResponse(
            simplejson.dumps({'error': _('Wrong HTTP Method')}),
            mimetype = 'application/json'
        )

    # try to log into facebook
    fb = Facebook(settings.FACEBOOK_API_KEY, settings.FACEBOOK_SECRET_KEY)

    if not fb.check_session(request):
        return HttpResponse(simplejson.dumps({'error': ERR}), mimetype = 'application/json')

    form = FBConnectForm(request.POST)

    if not request.user.is_authenticated():
        # Not logged in user trying to connect
        try:
            # Profile exists! Log in - don't create a new user
            profile = Profile.objects.get(fb_uid = fb.uid)
            user = profile.user

            if not form.is_valid():
                return HttpResponse(
                    simplejson.dumps({'error': form.errors.as_ul()}),
                    mimetype = 'application/json'
                )
            else:
                request.session['profile_update_time'] = form.cleaned_data.get('profile_update_time')

        except Profile.DoesNotExist:
            # There's no user registered yet and the username form's not sent yet
            # Send back the username form
            if not request.POST.has_key('create_username'):
                if form.is_valid():
                    request.session['profile_update_time'] = form.cleaned_data.get('profile_update_time')
                    return create_username_response(request, form)
                else:
                    return HttpResponse(
                        simplejson.dumps({'error': form.errors.as_ul()}),
                        mimetype = 'application/json'
                    )

            # There's no user registered yet
            # Process the username form
            if request.POST.has_key('create_username'):
                username_form = UsernameForm(request.POST,
                    choices = request.session['usernames'],
                    initial = dict(
                        create_username = '1',
                    )
                )
                if username_form.is_valid():
                    # Create the user
                    user = username_form.create_user()
                    profile = user.get_profile()

                else:
                    # Return the form again for another try
                    return HttpResponse(
                        simplejson.dumps(
                            dict(
                                message = 'new',
                                form = username_form.get_template({
                                    'uid': fb.uid,
                                })
                            )
                        )
                    )

        assert user
        assert profile
    else:
        # Logged in user trying to connect
        #profile = request.user.get_profile()
        profile, created = Profile.objects.get_or_create(user = request.user)
        user = request.user
        if not form.is_valid():
            return HttpResponse(
                simplejson.dumps(
                    dict(
                        error = ERR,
                    )
                )
            , mimetype = 'application/json')
        request.session['profile_update_time'] = form.cleaned_data.get('profile_update_time')

        if not profile.fb_uid:
            profile.fb_uid = fb.uid

    # do the import - if necessary
    if not profile.fb_profile_update_time or \
        request.session.get('profile_update_time') > profile.fb_profile_update_time:
        data = fb.users.getInfo(
            [fb.uid], [
                'name',
                'birthday',
                'first_name',
                'last_name',
                'current_location',
                'music',
                'pic',
                'pic_big',
                'pic_small',
                'pic_square',
                'about_me',
                'activities',
                'birthday',
                'books',
                'is_app_user',
                'has_added_app',
                'interests',
                'locale',
                'movies',
                'profile_update_time',
                'relationship_status',
                'religion',
                'sex',
                'status',
                'timezone'
            ]
        )[0]
        data['birthday'] = datetime.datetime.strptime(data['birthday'], '%B %d, %Y')
        data['profile_update_time'] = datetime.datetime.fromtimestamp(
            float(data['profile_update_time'])
        )
        profile.update_fb_data(data, fb)

    # LOGIN 
    user = authenticate(fb_uid = fb.uid)
    profile = user.get_profile()
    django_login(request, user)

    if request.session.has_key('usernames'):
        del request.session['usernames']

    redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '')

    if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
        redirect_to = settings.LOGIN_REDIRECT_URL


    if is_authed:
        return HttpResponse(
            simplejson.dumps({'message':_('Facebook connect was successfull!')}),
            mimetype = 'application/json'
        )
    else:
        return HttpResponse(
            simplejson.dumps({'redirect_to':redirect_to}),
            mimetype = 'application/json'
        )

def create_username_response(request, form):
    # Send back a few usernames
    first_name = form.cleaned_data.get('first_name')
    last_name = form.cleaned_data.get('last_name')
    birthday = form.cleaned_data.get('birthday').year

    choices = create_usernames(first_name, last_name, birthday)

    request.session['usernames'] = choices

    username_form = UsernameForm(choices = choices, initial = dict(
        create_username = '1',
    ))

    return HttpResponse(
        simplejson.dumps(
            dict(
                message = 'new',
                form = username_form.get_template({'uid':form.cleaned_data.get('uid')}),
            )
        ), mimetype = 'application/json'
    )

## Misc functions to create random usernames

def get_user_prefix(fname, lname, bday):
    return fname[:random.randint(0, len(fname))]


def get_user_postfix(fname, lname, bday):
    bday = str(bday)
    return u'%s%s' % (
        lname[:random.randint(0, len(lname))],
        bday[random.randint(0, len(bday)):]
    )

def create_usernames(first_name, last_name, birthday):
    usernames = list()

    while True and len(usernames) < 3:
        username = '%s%s' % (
            get_user_prefix(first_name, last_name, birthday),
            get_user_postfix(first_name, last_name, birthday),
        )
        try:
            user = User.objects.get(username = username)
        except User.DoesNotExist:
            usernames.append(username)

    other = ('other', 'Other:')
    tt = (
        (usernames[0], usernames[0]),
        (usernames[1], usernames[1]),
        (usernames[2], usernames[2]),
        other
    )
    return tt

